// ┏ ┓　　　┏ ┓
//┏┛ ┻━━━━━┛ ┻┓
//┃　　　　　　 ┃
//┃　　　━　　　┃
//┃　┳┛　  ┗┳　┃
//┃　　　　　　 ┃
//┃　　　┻　　　┃
//┃　　　　　　 ┃
//┗━┓　　　┏━━━┛
//  ┃　　　┃
//  ┃　　　┃
//  ┃　　　┗━━━━━━━━━┓
//  ┃　　　　　　　    ┣┓
//  ┃　　　　         ┏┛
//  ┗━┓ ┓ ┏━━━┳ ┓ ┏━┛
//    ┃ ┫ ┫   ┃ ┫ ┫
//    ┗━┻━┛   ┗━┻━┛
//
//
//  NSObject+Notification.m
//  
//
//  Created by ben zhipeng on 20/8/14.
//  Copyright (c) 2014 benzhipeng Company. All rights reserved.
//

#import "NSObject+Notification.h"
#import <objc/runtime.h>

static const void *notificationHelperKey = &notificationHelperKey;


@interface NSObjectNotificationHelper : NSObject

@property (nonatomic, strong) NSMutableDictionary *handlerDictionary;

@end

@implementation NSObjectNotificationHelper

- (id)init
{
    self = [super init];
    if (self) {
        self.handlerDictionary = [[NSMutableDictionary alloc] initWithCapacity:1];
    }
    
    return self;
}

- (void)dealloc
{
    [self.handlerDictionary removeAllObjects];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)didReceiveNotification:(NSNotification *)notification
{
    NSString *notificationName = [notification name];
    NotificationHandler handler = self.handlerDictionary[notificationName];
    if (handler) {
        handler(notificationName, [notification userInfo]);
    }
}

@end

@implementation NSObject (Notification)

- (void)addListenerForNotificationName:(NSString *)notificationName handler:(NotificationHandler)handler
{
    NSObjectNotificationHelper *helper = objc_getAssociatedObject(self, notificationHelperKey);
    if (!helper) {
        helper = [[NSObjectNotificationHelper alloc] init];
        objc_setAssociatedObject(self, notificationHelperKey, helper, OBJC_ASSOCIATION_RETAIN);
    }
    
    helper.handlerDictionary[notificationName] = handler;
    [[NSNotificationCenter defaultCenter] addObserver:helper selector:@selector(didReceiveNotification:) name:notificationName object:nil];
}

- (void)removeListenerForNotificationName:(NSString *)notificationName
{
    NSObjectNotificationHelper *helper = objc_getAssociatedObject(self, notificationHelperKey);
    if (helper) {
        [[NSNotificationCenter defaultCenter] removeObserver:helper name:notificationName object:nil];
    }
}

@end
